import Router from '@koa/router';
import { Context } from 'koa';
import { ResponseUtil } from '@/utils/response';

/**
 * 基础路由类
 */
export abstract class BaseRouter {
  protected router: Router;

  constructor(prefix?: string) {
    this.router = new Router({ prefix });
    this.setupRoutes();
  }

  /**
   * 抽象方法：子类必须实现具体的路由配置
   */
  protected abstract setupRoutes(): void;

  /**
   * 获取路由实例
   */
  public getRouter(): Router {
    return this.router;
  }

  /**
   * 获取路由中间件
   */
  public routes() {
    return this.router.routes();
  }

  /**
   * 获取允许的方法中间件
   */
  public allowedMethods() {
    return this.router.allowedMethods();
  }

  /**
   * 健康检查路由
   */
  protected setupHealthCheck(): void {
    this.router.get('/health', this.healthCheck);
    this.router.get('/ping', this.ping);
  }

  /**
   * 健康检查处理函数
   */
  private healthCheck = (ctx: Context): void => {
    ctx.status = 200;
    ctx.body = ResponseUtil.success({
      status: 'ok',
      timestamp: new Date().toISOString(),
      uptime: process.uptime(),
      memory: process.memoryUsage(),
      version: process.version,
      environment: process.env.NODE_ENV,
    }, '服务正常运行');
  };

  /**
   * Ping 处理函数
   */
  private ping = (ctx: Context): void => {
    ctx.status = 200;
    ctx.body = ResponseUtil.success({
      message: 'pong',
      timestamp: new Date().toISOString(),
    }, 'Ping 成功');
  };

  /**
   * 包装异步路由处理函数
   */
  protected wrapAsync(fn: (ctx: Context, next?: any) => Promise<any>) {
    return async (ctx: Context, next: any) => {
      try {
        await fn(ctx, next);
      } catch (error) {
        // 错误会被全局错误处理中间件捕获
        throw error;
      }
    };
  }

  /**
   * 记录路由访问日志
   */
  protected logRoute(_routeName: string) {
    return async (ctx: Context, next: any) => {
      const start = Date.now();
      
      await next();
      
      const responseTime = Date.now() - start;
      
      // 这里可以添加更详细的路由访问日志
      ctx.set('X-Response-Time', `${responseTime}ms`);
    };
  }

  /**
   * 缓存中间件
   */
  protected cache(duration: number = 300) {
    return async (ctx: Context, next: any) => {
      // 设置缓存头
      ctx.set('Cache-Control', `public, max-age=${duration}`);
      await next();
    };
  }

  /**
   * API 版本中间件
   */
  protected apiVersion(version: string) {
    return async (ctx: Context, next: any) => {
      ctx.set('API-Version', version);
      await next();
    };
  }
}

export default BaseRouter;